'''
协方差可以用来衡量数据的相关性的，
尤其在回归问题，用的比较多。

对于大量的数据，一般用协方差矩阵，
但这个矩阵的计算方式实际上与单独的协方差求值是不一样的，
协方差矩阵主要是使用矩阵转置、相乘的方式计算，
没有把原定公式计算到最后，也就是省略了一些计算过程，所以会快一些
参考：https://blog.csdn.net/blackyuanc/article/details/100703888
    https://blog.csdn.net/Harry_Jack/article/details/109280048
'''
import numpy as np


def Covariance001(x, y):
    '''
    :type x: np.array
    :type y: np.array
    :type return: float
    '''
    '''
    利用期望来计算协方差，
    cov(X,Y) = E(XY) - E(X)E(Y)
    '''
    EX = np.mean(x)
    EY = np.mean(y)
    E_X_Y = np.dot(x, y) / x.shape[0]
    res_COV = E_X_Y - EX * EY
    print(res_COV)
    return res_COV


def Covariance002(x, y):
    '''
    :type x: np.array
    :type y: np.array
    :type return: float
    '''
    '''
    利用方差来计算协方差，
    2cov(X,Y) = D(X+Y) - D(X)-D(Y)
    '''
    varX = np.var(x)
    varY = np.var(y)
    var_XY = np.var(x + y)
    res_COV = (var_XY - varX - varY) / 2
    print(res_COV)
    return res_COV

'''计算协方差矩阵'''
x1 = [1,2,3]
x2 = [3,1,1]
mat = np.stack((x1,x2), axis=1)
print(np.cov(mat))

p1 = np.array([1, 2, 3])
p2 = np.array([3, 4, 5])
p3 = np.array([4, 3, 1])
mat = np.stack((p1, p2, p3), axis=0)
print(mat)
print(np.cov(mat))

'''计算协方差'''
Covariance001(p1, p1)
Covariance002(p1, p1)









